package com.me.study.concurrent.threadPool;

import com.me.common.util.SleepUtil;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 这是一个线程池测试类：测试局部线程池 是否要手动关闭？
 *
 * TODO 答案是：要手动回收！并且 shutdown() 可以多次执行不报错
 *  虽然线程池对象是局部变量，但是他会保留核心线程数，不会随着局部方法的结束自动回收。
 *  并且随着局部方法的结束，我们不再使用（也拿不到，用不了）局部线程池对象，这种不再用，又回收不了就产生了内存泄漏
 *
 * @author ME
 * @date   2020/4/25
 */
public class TestThreadPool2 {

    public static void main(String[] args) throws Exception {
        //用于获取到本java进程，进而获取总线程数
        RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
        String jvmName = runtimeBean.getName();
        System.out.println("JVM Name = " + jvmName);

        long pid = Long.valueOf(jvmName.split("@")[0]);
        System.out.println("JVM PID  = " + pid);
        // SleepUtil.seconds(10);

        ThreadMXBean bean = ManagementFactory.getThreadMXBean();
        // 创建10个局部线程池，每个线程池提交了5个任务，最终会回收成2个线程
        int n = 10;
        for (int i = 0; i < n; i++) {
            createPool(bean);
        }
        Thread.sleep(5000);
        System.out.println("线程总数为 = " + bean.getThreadCount());
    }

    public static void createPool(ThreadMXBean bean) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 10, 3, TimeUnit.SECONDS, new SynchronousQueue<>());
        for (int j = 0; j < 5; j++) {
            executor.execute(() -> {
                System.out.println("当前线程总数为：" + bean.getThreadCount());
            });
        }
        // executor.shutdown();
        // executor.shutdown();
    }
}